<template>
  <view>
    <!-- 商品列表渲染 -->
    <view class="goods-list">
      <u-swipe-action>
        <u-swipe-action-item
          @click="swiperItemClick"
          :options="options"
          :name="item.goods_id"
          v-for="item in cartList" 
          :key="item.goods_id"
        >
          <view class="cart-item">
            <!-- radio 小程序组件库自带的 -->
            <radio :checked="item.goods_select" color="#EB4450" @click="changeSelect(item.goods_id)"/>
            <view class="cart-count">
              <!-- 步进器 组件 -->
              <!-- overLimit 事件会在数据超过阈值时触发 -->
              <!-- 这里为事件处理函数传递两个参数, 一个是当前项的 id, 另一个是默认获取到的 事件对象 $event -->
              <u-number-box @overlimit="overlimit(item.goods_id, $event)" :value="item.goods_count" :name="item.goods_id" @change="changeCount"/>
            </view>
            <!-- hover-class="none" 取消链接组件按下时的灰色样式 -->
            <!-- 在使用 navigator 进行跳转时, 需要携带路径参数再跳转, 参数为当前项商品 id, 用于后续渲染详情页 -->
            <navigator
              class="goods-item"
              hover-class="none"
              :url="`/pages/goods-detail/index?goods_id=${item.goods_id}`"
            >
              <!-- 商品图片 -->
              <image
                class="goods-image"
                :src="item.goods_small_logo"
                mode="aspectFit"
              />
              <!-- 商品信息 -->
              <view class="goods-info">
                <view class="goods-name">{{ item.goods_name }}</view>
                <view class="goods-price">{{ item.goods_price }}</view>
              </view>
            </navigator>
          </view>
        </u-swipe-action-item>
      </u-swipe-action>
    </view>
    <!-- 底部操作栏占位 -->
    <view class="bottom-bar">
      <!-- 固定定位的操作栏  -->
      <view class="bottom-bar-fixed">
        <view class="select">
          <radio class="select-radio" :checked="isAllSelected" color="#EB4450" @click="toggleAllSelected">
            全选
          </radio>
          <text class="select-radio"></text>
        </view>
        <!-- 合计 -->
        <view class="total">
          <text class="total-name">合计：</text>
          <text class="total-price">{{ selectedCartListPrice }}</text>
        </view>
        <!-- 结算 -->
        <view class="account" @click="goToPay">去结算({{ selectedCartListCount }})</view>
      </view>
    </view>

    <!-- 处理空页面 -->
    <u-empty mode="car" v-if="!cartList.length">
      <navigator
        url="/pages/index/index"
        open-type="switchTab"
        hover-class="none"
        >
        <u-button type="primary">去逛逛吧~</u-button>
      </navigator>
    </u-empty>
  </view>
</template>

<script>
import { mapGetters, mapState } from 'vuex'
import store from '../../store'
export default {
  data() {
    return {
      options: [
        {
          text: "删除",
          style: {
            backgroundColor: '#f56c6c'
          }
        },
      ],
    }
  },
  computed: {
    // 使用辅助函数, 展开 cartList 数组并进行深拷贝
    ...mapState({
      cartList: (state) => JSON.parse(JSON.stringify(state.cartList))
    }),
    // 直接使用 vuex 数据 并进行深拷贝
    // cartList() {
    //   return JSON.parse(JSON.stringify(this.$store.state.cartList))
    // }
    // 全选框状态, 筛选出被选中的商品, 计算被选中的商品数量, 计算被选中的商品总价
    ...mapGetters(['isAllSelected', 'selectedCartList', 'selectedCartListCount', 'selectedCartListPrice'])
  },
  onLoad(options) {

  },
  methods: {
    // 事件 - 改变选中状态
    changeSelect(goods_id) {
      // 获取购物车数据
      const cartList = this.cartList
      // 通过当前商品的 id 找到 当前商品对应的数组下标
      const index = cartList.findIndex(item => item.goods_id === goods_id)
      // 更新对应下标的选中状态, 每次点击, 就将选中状态取反
      cartList[index].goods_select = !cartList[index].goods_select
      // 将 vuex 中的数据更新为 更新后的选中状态
      this.$store.commit('updateCartList', cartList)
    },
    // 事件 - 商品数量变化时触发
    // 形参默认获取到的是一个对象 {value: 组件绑定的value, name: 组件绑定的name}
    // 这里进行解构
    changeCount({value, name}) {
      // console.log(value, name);
      const cartList = this.cartList
      const index = cartList.findIndex(item => item.goods_id === name)
      // 更新对应下标的数量数据
      cartList[index].goods_count = value
      // 更新 vuex 的数据
      this.$store.commit('updateCartList', cartList)
    },
    // 事件 - 当步进器数字超过阈值, 就会触发该事件
    // type：（minus已达最小值，plus已达最大值）
    // 形参接收 对应数据的 id , 以及默认获取到的事件对象
    // 使用 async 和 await 修饰符，等待用户做出选择, 拿到返回值后, 在进行下一步的操作
    async overlimit(goods_id, e) {
      // 通过 uni.showModel 显示对话模态框
      const [error, res] = await uni.showModal({
        title: '删除商品',
        content: '您确认要将该商品从购物车删除吗?'
      })
      // 如果没有错误, 则进行下一步判断, 如果用户点击了确认按钮, res.confirm 就会得到一个值为 true
      // 就可以根据数组下标, 将当前商品从购物车数组中删除, 并重新调用 commit 方法去更新 vuex 中的数据
      if (!error) {
        // 用户点击了确定按钮
        if (res.confirm) {
          // 调用函数删除商品数据
          this.deleteGoods(goods_id)
        }
      }
    },
    // 事件 - 滑动模块按钮点击事件
    // 形参默认获取到的是 当前项的下标 index, 以及 id {index: , name: }
    swiperItemClick({name}) {
      // 由于此处会调用 wx.showModal 方法, this 指向会发生变化
      // 所以这里需要手动制定一个 that 来储存我们需要的绑定的 this
      const that = this
      wx.showModal({
      title: '删除商品',
      content: '您确认要将该商品从购物车删除吗?',
      success (res) {
        if (res.confirm) {
          // 这里的 this 指向的是 success 函数
          // console.log(this);  // function success
          // 通过 that 来沿用上层作用域中的 this, 从而调用函数删除购物车商品
          that.deleteGoods(name)
          wx.showToast({title: '删除商品成功!', icon: 'success'})
        } else if (res.cancel) {
          console.log('用户点击取消')
          wx.showToast({title: '取消删除', icon: 'none'})
        }
      }
    })
    },
    // 事件 - 商品删除事件
    deleteGoods(goods_id) {
      // 获取购物车已有数据
      const cartList = this.cartList
      // 获取当前商品的数组下标
      const index = cartList.findIndex(item => item.goods_id === goods_id)
      // 利用 splice方法 将对应数组下标的数据从 购物车数组中删除
      cartList.splice(index, 1)
      // 更新 vuex 的数据
      this.$store.commit('updateCartList', cartList)
    },
    // 全选修改小选
    toggleAllSelected() {
      // 获取购物车数据
      const cartList = this.cartList
      // 获取计算属性中, 全选按钮的状态
      const isAllSelected = this.isAllSelected
      // 当点击全选按钮以后, 将所有小选框状态进行取反
      cartList.forEach(item => item.goods_select = !isAllSelected);
      // 更新 vuex 数据
      this.$store.commit('updateCartList', cartList)
    },
    // 事件 - 结算按钮
    goToPay() {
      // 先判断有没有选中的商品
      // 如果有商品, 就跳转结算页面
      if (this.selectedCartListCount) {
        uni.navigateTo({
          url: '/pages/pay/index'
        }) 
      } else {
        // 如果没有, 就提示用户
        uni.showToast({
          title: '请至少选择一件商品',
          icon: 'none'
        })
      }
    }
  },

  
}
</script>

<style lang="scss">
// 商品列表
.goods-list {
  .goods-item {
    display: flex;
    padding: 25rpx;
    .goods-image {
      width: 190rpx;
      height: 190rpx;
    }
    .goods-info {
      flex: 1;
      font-size: 24rpx;
      // 垂直方向两端对齐
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      padding: 20rpx;
      .goods-name {
        // 多行超出隐藏
        overflow: hidden;
        -webkit-line-clamp: 2;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-box-orient: vertical;
      }
      .goods-price {
        color: #eb4450;
        // 前面的价格符号
        &::before {
          content: '￥';
          font-size: 80%;
          margin-right: 5rpx;
        }
      }
    }
  }
}
// 购物车列表项
.cart-item {
  display: flex;
  align-items: center;
  padding-left: 20rpx;
  border-bottom: 1rpx solid #ddd;
  position: relative;
  // 清除最后一项的底边
  &:last-child {
    border-bottom: none;
  }
  // 步进器外层盒子，定位实现
  .cart-count {
    position: absolute;
    // 体验优化细节：扩大盒子范围，防止用户误操作
    // background-color: pink;
    padding: 20rpx;
    bottom: 0;
    right: 0;
  }
}

// 底部操作栏
.bottom-bar {
  // 占位用
  height: 100rpx;
  // 定位的操作栏
  .bottom-bar-fixed {
    height: 80rpx;
    position: fixed;
    z-index: 99;
    left: 0;
    right: 0;
    bottom: 0;
    // bottom: 100rpx;

    border-top: 1px solid #eee;
    background-color: #fff;
    display: flex;
    align-items: center;
    padding: 0 20rpx;

    .select {
      .select-radio {
        font-size: 24rpx;
        color: #999;
      }
    }

    .total {
      flex: 1;
      display: flex;
      align-items: center;
      margin-left: 40rpx;
      .total-name {
        font-size: 24rpx;
      }

      .total-price {
        color: #eb4450;
      }
    }

    .account {
      background-color: #eb4450;
      color: #fff;
      font-size: 22rpx;
      width: 150rpx;
      height: 52rpx;
      border-radius: 26rpx;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
}
</style>